namespace t0429 {
  interface ICommand {
    execute(): any;
  }
  // Command
  class Draw01Command implements ICommand {
    receiver: Gpu;
    constructor(re: Gpu) {
      this.receiver = re;
    }
    execute() {
      this.receiver.on();
    }
  }

  // received
  class Gpu {
    on() {
      console.log(`开灯`);
    }
    off() {
      console.log(`关灯`);
    }
  }

  // invoker
  class Jjs {
    command: ICommand[]=[];
    // 这个方法用来设置插槽控制的命令
    setCommand(command: ICommand) {
      this.command.push(command);
    }
    // 当按钮按下时这个方法就会被调用
    renderThisFrame() {
      for (const iterator of this.command) {
        iterator.execute(); // 使用当前命令衔接插槽，并调用它的 execute 方法
      }
    }
  }

  class main {
    run() {
      // 新建控制器
      let remoteInvoker = new Jjs();
      // 新建灯
      let light = new Gpu();
      // 生成将灯打开的命令
      let command = new Draw01Command(light); // 生成一个打开客厅灯的命令
      // 然后将命令注入遥控器
      remoteInvoker.setCommand(command);
      // 按下遥控器的开关执行这个命令
      remoteInvoker.renderThisFrame(); // 这样就可以执行任何命令了
    }
  }

  let t = new main();
  t.run();

  /**
   * 在集成终端打开此文件
   *
   * ts-node 0428.ts
   *
   */
}
